/**
 * 
 */
package com.bstek.code.service.templateservice.impl.masterslavevertical;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.velocity.VelocityContext;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.bstek.code.dao.DBInfoDao;
import com.bstek.code.model.ColumnInfo;
import com.bstek.code.model.MasterSlaveInfo;
import com.bstek.code.model.TableInfo;
import com.bstek.code.service.templateservice.ITempService;
import com.bstek.code.service.templateservice.TempServiceFactory;
import com.bstek.code.util.CodeUtil;
import com.bstek.code.util.JsonUtil;
import com.bstek.code.util.VelocityUtil;

/**
 * @description 
 * @author zhangkun
 * @date 2020年5月22日
 *
 */
@Component(MasterSlaveVerticalImpl.BEAN_ID)
public class MasterSlaveVerticalImpl implements ITempService{

	public static final String BEAN_ID = "MASTERSLAVEVERTICALIMPL";
	

	private String masterTabName;
	private String slaveTabName;
	private String masterKey;
	private String slaveKey;
	private List<ColumnInfo> masterCols;
	private List<ColumnInfo> slaveCols;
	
	private Map<String,String> tempFiles = new HashMap<String, String>();
	
	@Resource(name = DBInfoDao.BEAN_ID)
	private DBInfoDao dBInfoDao;
	
	public MasterSlaveVerticalImpl(){
		this.tempFiles.put("MasterEntity", "com/bstek/code/service/templateservice/impl/masterslavevertical/template/MASTERJAVABEAN.vm");
		this.tempFiles.put("SlaveEntity", "com/bstek/code/service/templateservice/impl/masterslavevertical/template/SLAVEJAVABEAN.vm");
		this.tempFiles.put("Dao", "/com/bstek/code/service/templateservice/impl/masterslavevertical/template/DAO.vm");
		this.tempFiles.put("Service", "/com/bstek/code/service/templateservice/impl/masterslavevertical/template/SERVICE.vm");
		this.tempFiles.put("Controller", "/com/bstek/code/service/templateservice/impl/masterslavevertical/template/CONTROLLER.vm");
		this.tempFiles.put("View", "/com/bstek/code/service/templateservice/impl/masterslavevertical/template/CRUDForm.view.vm");
	}
	
	@Override
	public String create(Map<String, Object> parameter) throws Exception {
		String workSpaceSrc= (String) parameter.get("workSpaceSrc");
		String rootPkg= (String) parameter.get("rootPkg");
		String preBeanId = (String)parameter.get("preBeanId")==null?"":(String)parameter.get("preBeanId");			
		this.masterTabName = (String) parameter.get("masterTab");
		this.slaveTabName = (String) parameter.get("slaveTab");
		this.masterKey = (String) parameter.get("masterKey");
		this.slaveKey = (String) parameter.get("slaveKey");
		this.masterCols = JsonUtil.jsonToList((String) parameter.get("masterCols"),ColumnInfo.class);
		this.slaveCols = JsonUtil.jsonToList((String) parameter.get("slaveCols"),ColumnInfo.class);
		validateParams(workSpaceSrc,rootPkg);
		//从数据库查询表信息
		TableInfo masterTab = dBInfoDao.getTablesByNames(masterTabName).get(0);
		TableInfo slaveTab = dBInfoDao.getTablesByNames(slaveTabName).get(0);
		//初始化velocityContext
		VelocityContext context = VelocityUtil.initContext();
		//创建文件夹
		String pkgPath = createDir(workSpaceSrc, rootPkg);
		context.put("info", getInfo(masterTab, slaveTab, rootPkg, preBeanId));
		
		return createFiles(masterTab, slaveTab, pkgPath, context);
	}
	

	@Override
	@PostConstruct
	public void putMap() {
		TempServiceFactory.putBean("4", this);

	}

	
	@Override
	public List<Map<String, Object>> generateMenuList(String workSpaceSrc,
			String pkgFilepath) {
		List<Map<String, Object>> dirs = new ArrayList<Map<String, Object>>();
		dirs.add(CodeUtil.generateMenu("entity",workSpaceSrc+"/"+pkgFilepath+"/entity","java实体类(ORM bean)"));
		dirs.add(CodeUtil.generateMenu("dao",workSpaceSrc+"/"+pkgFilepath+"/dao","数据库访问层"));
		dirs.add(CodeUtil.generateMenu("service",workSpaceSrc+"/"+pkgFilepath+"/service","服务层"));
		dirs.add(CodeUtil.generateMenu("controller",workSpaceSrc+"/"+pkgFilepath+"/view/{funName}","控制层"));
		dirs.add(CodeUtil.generateMenu("view",workSpaceSrc+"/"+pkgFilepath+"/view/{funName}","视图层"));
		return dirs;
	}


	@Override
	public List<Map<String, Object>> generateFileNames(String tabs,
			String filePath, String type) {
		List<Map<String, Object>> dirs = new ArrayList<Map<String, Object>>();
		String[] t = tabs.split(",");
		if("entity".equals(type)){
			for(int i = 0; i < t.length; i++){
				dirs.add(CodeUtil.generaeFileName(type, filePath, t[i], CodeUtil.getEntityName(t[i])+".java"));
			}
		}
		
		if("dao".equals(type)){
			dirs.add(CodeUtil.generaeFileName(type, filePath, t[0] + "," + t[1], CodeUtil.getEntityName(t[0])+"Dao.java"));
		}
		
		if("service".equals(type)){
			dirs.add(CodeUtil.generaeFileName(type, filePath, t[0] + "," + t[1], CodeUtil.getEntityName(t[0])+"Service.java"));
		}
		
		if("controller".equals(type)){
			dirs.add(CodeUtil.generaeFileName(type, filePath, t[0] + "," + t[1], CodeUtil.getEntityName(t[0])+"Controller.java"));
		}
		
		if("view".equals(type)){
			dirs.add(CodeUtil.generaeFileName(type, filePath, t[0] + "," + t[1], CodeUtil.getEntityName(t[0])+".view.xml"));
		}
		
		return dirs;
	}

	/**
	 * 
	 * @description 校验参数
	 * @author zhangkun
	 * @date 2020年5月25日
	 * @param workSpaceSrc
	 * @param rootPkg
	 * @param tabs
	 */
	private void validateParams(String workSpaceSrc , String rootPkg ){
		Assert.hasText(workSpaceSrc, "workSpaceSrc不能为空");
		Assert.hasText(rootPkg, "rootPkg不能为空");
		Assert.hasText(masterTabName, "masterTab不能为空");
		Assert.hasText(slaveTabName, "slaveTab不能为空");
		Assert.hasText(masterKey, "masterKey不能为空");
		Assert.hasText(slaveKey, "slaveKey不能为空");
	}
	
	/**
	 * 
	 * @description 根据跟路径和包名创建文件夹
	 * @author zhangkun
	 * @date 2020年5月21日
	 * @param workSpaceSrc
	 * @param rootPkg
	 * @return
	 */
	private String createDir(String workSpaceSrc, String rootPkg) {
		//检查或创建包根目录
		String pkgFilepath=StringUtils.replace(rootPkg, ".", "/");
		String pkgPath=workSpaceSrc+"/"+pkgFilepath;
		File pkgFile=new File(pkgPath);
		if(!pkgFile.exists()){
			//文件目录不存在，自动创建
			pkgFile.mkdirs();
		}
		return pkgPath;
	}
	
	
	/**
	 * 
	 * @description 获取主从表info类，用于构建volocity模板
	 * @author zhangkun
	 * @date 2020年5月25日
	 * @param masterTab
	 * @param slaveTab
	 * @param rootPkg
	 * @param preBeanId
	 * @return
	 */
	private MasterSlaveInfo getInfo(TableInfo masterTab, TableInfo slaveTab , String rootPkg, String preBeanId){
		MasterSlaveInfo info = new MasterSlaveInfo(masterTab.getjName(),slaveTab.getjName(), rootPkg); 
		if (StringUtils.hasText(preBeanId)) {
			preBeanId += ".";
			info.setPrBeanId(preBeanId.toUpperCase());
		}
		info.setMasterCols(this.masterCols);
		info.setSlaveCols(this.slaveCols);
		info.setControllerBeanId((preBeanId  + masterTab.getjName() + "Controller").toUpperCase());// 设置bo的beanId
		info.setDaoBeanId((preBeanId  + masterTab.getjName() + "Dao").toUpperCase());
		info.setServiceBeanId((preBeanId  + masterTab.getjName() + "Service").toUpperCase());
		info.setMasterTab(masterTab);
		info.setSlaveTab(slaveTab);
		info.setMasterKey(findColumn(masterTab.getCols(),this.masterKey));
		info.setSlaveKey(findColumn(slaveTab.getCols(),this.slaveKey));
		return info;
	}
	
	/**
	 * 
	 * @description 生成文件名
	 * @author zhangkun
	 * @date 2020年5月21日
	 * @param javaBean
	 * @param type tempFiles的key
	 * @return
	 */
	private String generateFileName(String javaBean,String type){
		if("View".equals(type))
			return javaBean + ".view.xml";
		
		if("Entity".equals(type))
			return javaBean + ".java";
		
		return javaBean + type + ".java";
	}
	
	/**
	 * @description 生成文件路径并创建文件夹
	 * @author zhangkun
	 * @date 2020年5月21日
	 * @param type tempFiles的key
	 * @param filePath 根路径
	 * @param javaBean
	 * @return 文件路径
	 */
	private String generateFilePath(String type,String filePath,String javaBean){
		
		String path = filePath + File.separator + type.toLowerCase();
		if("View".equals(type) || "Controller".equals(type)){
			path = filePath + File.separator + "view" + File.separator + javaBean.toLowerCase();
		}
		
		mkdirs(path);
		return path;
		
	}
	
	/**
	 * 
	 * @description 根据路径构建目录
	 * @author zhangkun
	 * @date 2020年5月22日
	 * @param path
	 */
	private void mkdirs(String path) {
		File file = new File(path);
		if(!file.exists())file.mkdirs();
	}
	
	/**
	 * 
	 * @description 根据列名找到对应列
	 * @author zhangkun
	 * @date 2020年5月27日
	 * @param columns
	 * @param name
	 * @return
	 */
	private ColumnInfo findColumn(List<ColumnInfo> columns,String name){
		if(!StringUtils.hasText(name)) return null;
		for(ColumnInfo col:columns){
			if(name.equals(col.getName()))
				return col;
		}
		return null;
	}
	
	/**
	 * 
	 * @description 生成文件
	 * @author zhangkun
	 * @date 2020年5月25日
	 * @param masterTab
	 * @param slave
	 * @param pkgPath
	 * @param context
	 * @return
	 */
	private String createFiles(TableInfo masterTab,TableInfo slaveTab,String pkgPath,VelocityContext context){
		try{
			VelocityUtil.generateFile(context, generateFilePath("Entity",pkgPath,masterTab.getjName()) + File.separator + generateFileName(masterTab.getjName(),"Entity"), tempFiles.get("MasterEntity"));
			VelocityUtil.generateFile(context, generateFilePath("Entity",pkgPath,slaveTab.getjName()) + File.separator + generateFileName(slaveTab.getjName(),"Entity"), tempFiles.get("SlaveEntity"));
			VelocityUtil.generateFile(context, generateFilePath("Dao",pkgPath,masterTab.getjName()) + File.separator + generateFileName(masterTab.getjName(),"Dao"), tempFiles.get("Dao"));
			VelocityUtil.generateFile(context, generateFilePath("Service",pkgPath,masterTab.getjName()) + File.separator + generateFileName(masterTab.getjName(),"Service"), tempFiles.get("Service"));
			VelocityUtil.generateFile(context, generateFilePath("Controller",pkgPath,masterTab.getjName()) + File.separator + generateFileName(masterTab.getjName(),"Controller"), tempFiles.get("Controller"));
			VelocityUtil.generateFile(context, generateFilePath("View",pkgPath,masterTab.getjName()) + File.separator + generateFileName(masterTab.getjName(),"View"), tempFiles.get("View"));
		
		} catch (Exception e){
			e.printStackTrace();
			return "主从表crud生成失败";
		}
		return "主从表crud生成成功";
	}
}
